<template>
  <div class="the-list">
    <el-card class="box-card">
      <el-form inline :model="tableData.query" class="demo-form-inline">
        <el-form-item label="优惠劵名称">
          <el-input v-model="tableData.query.couponName"></el-input>
        </el-form-item>
        <el-form-item label="使用活动类型">
          <el-select v-model="tableData.query.couponUseType">
            <el-option v-for="item in couponList.couponUseType" :key="item.key" :label="item.name" :value="item.key" />
          </el-select>
        </el-form-item>
        <el-form-item label="优惠劵类型">
          <el-select v-model="tableData.query.couponType">
            <el-option v-for="item in couponList.couponType" :key="item.key" :label="item.name" :value="item.key" />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="tableFn.getTableList()">查询</el-button>
          <el-button type="primary" @click="tableFn.onResetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="box-card" style="margin-top: 20px">
      <div style="display: flex;margin-bottom: 10px">
        <label style="flex: 1">数据列表</label>
        <el-button type="primary" @click="addEditFn.openPanel('add')">添加</el-button>
      </div>
      <template-table
          v-model:data="tableData.list"
          :columns="tableData.columns"
          height="450"
          v-model:totalRecord="tableData.total"
          :operateWidth="220"
          @callback="tableFn.callback">
        <template v-slot:couponUseType="{ row }">
          <label>
            {{ getItemFromArray(couponList.couponUseType , row.couponUseType) }}
          </label>
        </template>
        <template v-slot:couponType="{ row }">
          <label>
          {{ getItemFromArray(couponList.couponType , row.couponType) }}
        </label>
        </template>
        <template v-slot:userType="{ row }">
          <label>
            {{ getItemFromArray(couponList.userType , row.userType) }}
          </label>
        </template>
        <template v-slot:showPage="{ row }">
          <label>
            {{ getItemFromArray(couponList.showPage , row.showPage) }}
          </label>
        </template>
        <template v-slot:couponMoney="{ row }">
          <label>
            {{ row.couponMoney/100}}
          </label>
        </template>
        <template v-slot:orderMinMoney="{ row }">
          <label>
            {{ !!row.orderMinMoney ? row.orderMinMoney/100:'--' }}
          </label>
        </template>
        <template v-slot:couponStatus="{ row }">
          <label :style=" {color: ['#F56C6C' , '#67C23A'][row.couponStatus] }">
            {{ getItemFromArray(couponList.couponStatus , row.couponStatus) }}
          </label>
        </template>
        <template v-slot:operate="{ row }">
          <el-button size="small" type="primary" plain @click="detailFn.gotoDetail(row)">详情</el-button>
          <el-button size="small" type="primary" plain @click="stateFn.sureUpdate(row)">{{ row.couponStatus == '1' ? '下架' : '上架' }}</el-button>
          <el-button size="small" type="primary" plain @click="qrcodeFn.openPanel(row)">二维码</el-button>
        </template>
      </template-table>
    </el-card>

    <el-dialog
        :title="addEditData.isEdit?'修改优惠券':'新增优惠券'"
        v-model="addEditData.visible"
        width="650px"
        :before-close="addEditFn.closePanel"
        :close-on-press-escape="false"
        :close-on-click-modal="false"
        :destroy-on-close="true"
        center>
      <div>
        <el-form ref="form" :rules="addEditData.rules" :model="addEditData.post" label-width="150px">
          <el-form-item label="优惠券有效期" prop="effectiveData">
            <el-date-picker
              type="datetimerange"
              range-separator="至"
              start-placeholder="请选择开始时间"
              end-placeholder="请选择结束时间"
              format="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss"
              v-model="addEditData.post.effectiveData"
              style="width: 95.5%"
              @change="(effectiveData) => {addEditData.post.effectiveStartTime = effectiveData[0];addEditData.post.effectiveEndTime = effectiveData[1]}"
              >
            </el-date-picker>
          </el-form-item>
          <el-form-item label="优惠券名称" prop="couponName">
            <el-input v-model="addEditData.post.couponName"></el-input>
          </el-form-item>
          <el-form-item label="适用活动类型" prop="couponUseType">
            <el-select v-model="addEditData.post.couponUseType">
              <el-option v-for="item in couponList.couponUseType" :key="item.key" :label="item.name" :value="item.key" />
            </el-select>
          </el-form-item>
          <el-form-item label="优惠券类型" prop="couponType">
            <el-select v-model="addEditData.post.couponType">
              <el-option v-for="item in couponList.couponType" :key="item.key" :label="item.name" :value="item.key" />
            </el-select>
          </el-form-item>
          <el-form-item label="用户类型" prop="userType">
            <el-radio-group v-model="addEditData.post.userType">
              <el-radio v-for="item in couponList.userType" :key="item.key" :label="item.key">{{ item.name }}</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item v-if="addEditData.post.userType == 3">
            <el-input type="textarea" v-model="addEditData.post.userInfo" placeholder="请输入用户id（多个用户以英文逗号隔开）"></el-input>
          </el-form-item>
          <el-form-item label="抵扣金额" prop="couponMoney">
            <el-input v-model="addEditData.post.couponMoney"></el-input>
          </el-form-item>
          <el-form-item label="订单最小金额" prop="orderMinMoney">
            <el-input v-model="addEditData.post.orderMinMoney"></el-input>
          </el-form-item>
          <el-form-item label="张数" prop="couponCount">
            <el-input v-model="addEditData.post.couponCount"></el-input>
          </el-form-item>
          <el-form-item label="每一个用户领取张数" prop="userGetRestrict">
            <el-input v-model="addEditData.post.userGetRestrict"></el-input>
          </el-form-item>
          <el-form-item label="是否在领券中心页面显示" label-width="170px">
            <el-switch v-model="addEditData.post.showPage" :active-value="1" :inactive-value="0"></el-switch>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
        <el-button style="margin-right: 30px" @click="addEditFn.closePanel()">取 消</el-button>
        <el-button type="primary" @click="addEditFn.submitData(form)">确 定</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog
        title="二维码"
        v-model="qrcodeData.visible"
        width="300px"
        center>
      <el-image :src="qrcodeData.qrImg"/>
      <div style="display: flex; justify-content: space-between; align-items: center;">
        <label style="margin-right: 20px">{{qrcodeData.qrImg}}</label>
        <el-button size="small" v-clipboard:copy="qrcodeData.qrImg" v-clipboard:error="qrcodeFn.onError" v-clipboard:success="qrcodeFn.clipboardSuccess">复制</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>

import {getCurrentInstance, reactive} from "vue";
import { getCouponList , createCoupon , updateCoupon , qrCode}  from "@/api/coupon.js";
import {getItemFromArray , couponList} from "@/utils/tool.js";
import TemplateTable from "@/components/TemplateTable";
import {ElMessage, ElMessageBox} from "element-plus";
import {useRouter} from "vue-router";
import {dataURItoBlob} from "@/utils/utils";
import {client, randomWord} from "@/utils/alioss";

export default {
  name: "couponList",
  components: { TemplateTable },
  setup() {
    // 默认数据备份，以便重置或恢复
    const { $data: tableData, $fn: tableFn } = tableModule();
    const { $data: detailData, $fn: detailFn } = detailModule();
    const { $data: stateData, $fn: stateFn } = stateModule(tableFn);
    const { $data: addEditData, $fn: addEditFn } = addOrEditModule(tableData, tableFn);
    const { $data: qrcodeData, $fn: qrcodeFn } = qrcodeModule();
    const form = getCurrentInstance().refs.form

    return {
      tableData,
      tableFn,
      detailData,
      detailFn,
      stateData,
      stateFn,
      addEditData,
      addEditFn,
      qrcodeData,
      qrcodeFn,
      form,
      couponList,getItemFromArray
    };
  },
};

// 表格功能模块，包括搜索，分页等
function tableModule() {
  const backup = {
    query: {
      pageSize: 10,
      page: 1,
      total: 0,
      couponName: null,
      couponUseType: null,
      couponType: null
    },
  };

  const $data = reactive({
    query: { ...backup.query },
    list: [],
    // 用于定义列属性
    columns: [ // 列信息
      {
        label: '优惠卷名称', // 列名
        prop: 'couponName', // 字段名跟实体类属性名对应
        width: 100
      },
      {
        label: '使用活动类型',
        prop: 'couponUseType',
        width: 110,
        slot: true // 是否自定义插槽
      },
      {
        label: '优惠劵类型',
        prop: 'couponType',
        width: 100,
        slot: true
      },
      {
        label: '用户类型',
        prop: 'userType',
        width: 100,
        slot: true
      },
      {
        label: '抵扣金额',
        prop: 'couponMoney',
        slot: true
      },
      {
        label: '订单最小金额',
        prop: 'orderMinMoney',
        width: 80,
        slot: true
      },
      {
        label: '总张数',
        prop: 'couponCount'
      },
      {
        label: '领劵页显示',
        prop: 'showPage',
        width: 100,
        slot: true
      },
      {
        label: '上架状态',
        prop: 'couponStatus',
        width: 100,
        slot: true
      },
      {
        label: '有效期开始时间',
        prop: 'effectiveStartTime',
        width: 160
      },
      {
        label: '有效期结束时间',
        prop: 'effectiveEndTime',
        width: 160
      },
      {
        label: '创建时间',
        prop: 'createdAt',
        width: 160
      },
      {
        label: '创建人',
        prop: 'createName',
      }
    ],
    total: 0,
  });
  const $fn = {
    getTableList() {
      getCouponList($data.query).then((res) => {
        if (res.code === 0) {
          $data.list = res.data.items;
          $data.total = res.data.pagination.total_record;
        }
      });
    },
    onResetQuery() {
      $data.query = { ...backup.query };
      $fn.getTableList();
    },
    onSubmit() {
      $fn.getTableList();
    },
    callback(keyword , params) { // 子组件可用的回调操作，包括分页数据、条件查询、重置等
      switch (keyword) {
        case 'setPageInfo': // 分页回调
          $data.query.page = params.page
          $data.query.pageSize = params.pageSize
          $fn.onSubmit()
          break;
        default:
          ElMessage.error("Undefined callback keyword ！！");
          break;
      }
    }

  };

  $fn.getTableList();

  return {
    $data,
    $fn,
  };
}

// 详情
function detailModule() {

  const router = useRouter();

  const $data = reactive({
    showPanel: false,
    detail: {}, //详情数据
  });
  const $fn = {
    gotoDetail(row) {
      router.push('/coupon/detail/' + row.id+"?view=detail");
    },
  };
  return {
    $data,
    $fn,
  };
}

// 修改状态
function stateModule(tableFn) {
  const $fn = {
    sureUpdate(row) {
      let text = row.couponStatus ? '下架' : '上架';
      ElMessageBox.confirm(`是否确认${text}该优惠券？`, `确认${text}`, {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        $fn.updateItem(row);
      }).catch(() => {});
    },
    updateItem(row) {
      let text = row.couponStatus == '1' ? '下架' : '上架';
      let {id , couponStatus} = row
      couponStatus = couponStatus == '1' ? '0':'1'
      let req = {id,couponStatus};
      updateCoupon(req).then((res)=>{
        if(res.code===0){
          ElMessage.success(`${text}成功！`);
          tableFn.getTableList();
        }
      })
    },
  };
  return {
    $fn,
  };
}

// 新增、编辑
function addOrEditModule(tableData, tableFn) {
  const backup = {
    id: null,
    couponName: null,
    couponUseType: 0,
    couponType: 0,
    userType: 3,
    userInfo: null,
    couponMoney: null,
    orderMinMoney: null,
    couponCount: null,
    userGetRestrict: null,
    couponStatus: null,
    showPage: null,
    effectiveData: null,
    effectiveStartTime: null,
    effectiveEndTime: null
  }
  const $data = reactive({
    visible: false,
    isEdit: false,
    post: { ...backup }, //提交的数据
    rules: {
      couponName: [
        { required: true, message: '请输入优惠券名称', trigger: 'blur' },
        { min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
      ],
      couponUseType: [
        { required: true, message: '请选择适用活动类型', trigger: 'blur' }
      ],
      couponType: [
        { required: true, message: '请选择优惠券类型', trigger: 'blur' }
      ],
      userType: [
        { required: true, message: '请选择用户类型', trigger: 'blur' }
      ],
      couponMoney: [
        { required: true, message: '请填写抵扣金额', trigger: 'blur' },
        { pattern: /(^[1-9]\d{0,9}(\.\d{1,2})?$)|(^0(\.\d{1.2}))/, message: '金额格式错误' }
      ],
      orderMinMoney: [
        { pattern: /^(([1-9]{1}\d{0,9})|(0{1}))(\.\d{1,2})?$/, message: '金额格式错误' }
      ],
      couponCount: [
        { required: true, message: '请填写张数', trigger: 'blur' },
        { pattern: /^[1-9]\d*$/, message: '张数格式不正确' }
      ],
      userGetRestrict: [
        { required: true, message: '请填写每一个用户领取张数', trigger: 'blur' },
        { pattern: /^[1-9]\d*$/, message: '张数格式不正确' }
      ],
      effectiveData: [
        { required: true, message: '请选择有效起止日期', trigger: 'blur' }
      ]
    } // 表单校验
  });
  const $fn = {
    openPanel(operate, row) {
      if (operate === "add") {
        $data.isEdit = false;
      } else if (operate === "edit") {
        $data.isEdit = true;
        $data.post = { ...row }
        let {effectiveStartTime ,effectiveEndTime} = row
        $data.post.effectiveData = [effectiveStartTime ,effectiveEndTime]
      }
      $data.visible = true;
    },
    closePanel() {
      $data.visible = false;
      $data.post = { ...backup }
    },
    submitData(form) {
      console.log("req data:", $data.post);
      if (!form) {
        return
      }
      form.validate((valid) => {
        if (valid) {
          let { id, couponName, couponUseType, couponType, userType, userInfo, couponMoney, orderMinMoney, couponCount, userGetRestrict, couponStatus, showPage, effectiveStartTime, effectiveEndTime } = $data.post;
          if (couponUseType  == 1 && (!orderMinMoney)) {
            ElMessage.error('请填写订单最小金额')
            return
          }
          if(couponUseType === 1 && Number(orderMinMoney)<Number(couponMoney) ){
            ElMessage.error('满减券最小订单金额必须要大于等于抵扣金额')
            return
          }
          if($data.isEdit){
            let req = { id, couponName, couponUseType, couponType, userType, userInfo, couponMoney, orderMinMoney, couponCount, userGetRestrict, couponStatus, showPage, effectiveStartTime, effectiveEndTime };
            updateCoupon(req).then(res=>{
              if(res.code===0){
                ElMessage.success("修改成功！");
                $fn.closePanel();
                tableFn.getTableList();
              }
            })
          }else{
            let req = { couponName, couponUseType, couponType, userType, userInfo, couponMoney:couponMoney*100, orderMinMoney:orderMinMoney?orderMinMoney*100:0, couponCount, userGetRestrict, couponStatus, showPage, effectiveStartTime, effectiveEndTime };
            if (userType == '3' && !userInfo) {
              ElMessage.error("请填写用户id")
              return
            }
            createCoupon(req).then(res=>{
              if(res.code===0){
                ElMessage.success("添加成功！");
                $fn.closePanel();
                tableFn.getTableList();
              }
            })
          }
        }
      })
    }
  }
  return {
    $data,
    $fn,
  };
}

function qrcodeModule() {
  const $data = reactive({
    visible: false,
    value: null,
    qrImg: ''
  })
  const $fn = {
    openPanel(row) {
      const data = {
        scene: 'mp4',
        page: 'pages/getSingleCoupon',
        param: 'couponId=' + row.id
      }
      qrCode(data).then(async res=>{
        if(res.code===0){
          const blobData = dataURItoBlob("data:image/png;base64,"+ res.data);
          var fileName = `img/${randomWord(true, 20)}${+new Date()}.png`
          client()
              .put(fileName, blobData)
              .then((result) => {
                $data.qrImg = "https://img.qumoyugo.com/" + result.name
              })
              .catch((err) => {
                this.$message.error(err);
              });
          $data.value = row.id
          $data.visible = true
        }
      })
    },
    closePanel() {
      $data.visible = false
      $data.value = null
    },
    clipboardSuccess() {
      ElMessage.success("复制成功");
    },
    onError() {
      ElMessage.error("复制失败");
    },
  }

  return {
    $data,
    $fn
  }
}

</script>

<style scoped lang="scss">
@import "@/styles/tablePage.scss";
</style>
